/*
 * Copyright (c) 2008, Yifu Huang
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of SleekIce nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.sleekice.gui;

import com.sleekice.core.Renderable;
import com.sleekice.core.Updatable;
import java.awt.Color;
import java.awt.Graphics2D;

public class ScrollBar implements Renderable, Updatable, Widget {

    private static final Color DEF_BORDER_C = Color.black;
    private Color borderC;
    private Button topButton;
    private Button bottomButton;
    private Button innerBar;
    private int x;
    private int y;
    private int width;
    private int height;
    private int innerHeight;
    private int maxValue;
    private int value;
    private Scrollable object;

    public ScrollBar(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        innerHeight = height - 2 * width;

        borderC = DEF_BORDER_C;

        topButton = new Button(x, y, width, width);
        topButton.setBobbleOnMouseOver(false);
        bottomButton =
            new Button(x, y + height - width, width, width);
        bottomButton.setBobbleOnMouseOver(false);
        innerBar = new Button(x,y+width,width,innerHeight);
        innerBar.setBobbleOnMouseOver(false);
        
        setMaxValue(1);
    }

    public void assignTo(Scrollable object) {
        this.object = object;
        object.initScrollbar(this);
    }

    public Button getBottomButton() {
        return bottomButton;
    }

    public Button getTopButton() {
        return topButton;
    }

    public int getValue() {
        return value;
    }

    public void increaseMaxValue(int increment) {
        maxValue += increment;
        if (maxValue < 0) {
            maxValue = 0;
        }
        updateInnerBar();
    }

    public void increaseValue(int increment) {
        value += increment;
        if (value > maxValue-1) {
            value = maxValue-1;
        }
        if (value < 0) {
            value = 0;
        }
        updateInnerBar();
    }

    public void render(Graphics2D g) {
        g.setColor(Color.black);
        g.fillRect(x, y, width, height);

        /**
         * Draw the inner bar only if there is a maxValue.
         */
        if (maxValue > 0) {
            //g.setColor(Color.blue);
            //g.fillRect(x, y + width + value * innerHeight / maxValue, width,
            //    innerHeight / maxValue);
            innerBar.render(g);
        }
        
        g.setColor(borderC);
        g.drawRect(x, y, width, height);

        /* draw the button arrows */
        topButton.render(g);
        bottomButton.render(g);
    }

    public void setMaxValue(int maxValue) {
        if (maxValue >= 0) {
            this.maxValue = maxValue;
        }
        updateInnerBar();
    }

    public void update(double elapsedTime) {
        topButton.update(elapsedTime);
        bottomButton.update(elapsedTime);

        if (object != null) {
            if (topButton.isClicked()) {
                object.scrollUp();
            }

            if (bottomButton.isClicked()) {
                object.scrollDown();
            }
        }
    }
    
    private void updateInnerBar() {
        if (maxValue == 0) {
            innerBar.resize(width, innerHeight);
            innerBar.relocate(x, y);
        }
        else {
            innerBar.resize(width, innerHeight / maxValue);
            innerBar.relocate(x, y + width + value * innerHeight / maxValue);
        }
    }

    private boolean enabled_ = true;
    public boolean isEnabled() {
        return enabled_;
    }

    private boolean visible_ = true;
    public boolean isVisible() {
        return visible_;
    }

    public void setEnabled(boolean enabled) {
        enabled_ = enabled;
    }

    public void setVisible(boolean visible) {
        visible_ = visible;
    }
}